home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / faq-s.zip / XCRT.PAS < prev   
Pascal/Delphi Source File  |  1989-05-12  |  10KB  |  353 lines

  1. {Saved as: XCRT.PAS - eXtended CRT unit for TP 4.0
  2. Pat Anderson, 3/27/88}
  3.  
  4. UNIT xcrt;
  5.  
  6. INTERFACE
  7. USES crt, dos;
  8.   TYPE
  9.     Str1 = string[1];
  10.     Str2 = string[2];
  11.     Str15 = string[15];
  12.     Str30 = string[30];
  13.     Str79 = string[79];
  14.  
  15.   VAR
  16.     Regs : Registers;         {predefined in dos unit}
  17.     ScreenBase : word;        { Set to $b000 for mono,
  18.                                 $b800 for color}
  19.     Monochrome : boolean;     {True if monochrome, false
  20.                                if color}
  21.     InsertFlag : boolean;     {used by EditLine procedure}
  22.  
  23.   FUNCTION GetKey : Str2;
  24.    {Function that waits for a key press, no echo to
  25.    screen, returns a string of type Str2, logical length
  26.    of 1 or 2.  If length is 1, element [1] contains
  27.    the normal ASCII code of the key pressed.  If the
  28.    length is 2, element [2] contains the extended
  29.    (scan) code of the key pressed}
  30.  
  31.   PROCEDURE AdaptorType;
  32.   {Procedure that sets global variables ScreenBase
  33.   to correct segment for mono or color adaptor, and
  34.   Boolean variable Monochrome to True or False}
  35.  
  36.   PROCEDURE CursorOff;
  37.   {Procedure turns the cursor off}
  38.  
  39.   PROCEDURE NormCursorOn;
  40.   {Procedure that turns underscore cursor on}
  41.  
  42.   PROCEDURE BlockCursorOn;
  43.   {Procedure that turns block cursor on}
  44.  
  45.   PROCEDURE ReverseVideo;
  46.   {procedure that turns on reverse video}
  47.  
  48.   PROCEDURE BlinkOn;
  49.   {procedure that turns on blinking}
  50.  
  51.   PROCEDURE Pad (VAR LineToPad : str79; PadLength : byte);
  52.  
  53.   PROCEDURE Strip (VAR LineToStrip :  str79);
  54.  
  55.   PROCEDURE EditLine (VAR line : str79; VAR cursor : byte;
  56.                       col, row, fieldlength : byte;
  57.                       VAR exit_key : str2);
  58.  
  59. IMPLEMENTATION
  60.  
  61.   FUNCTION GetKey;
  62.     VAR ch : char;
  63.         t  : Str2;
  64.   BEGIN
  65.     ch := ReadKey;
  66.     t  := ch;
  67.     IF (ch = chr(0)) AND KeyPressed THEN
  68.       BEGIN
  69.         ch := ReadKey;
  70.         t  := t + ch;
  71.        END;
  72.     GetKey := t
  73.   END; {of GetKey function}
  74.  
  75.   PROCEDURE AdaptorType;
  76.     BEGIN
  77.       INTR (17,Regs);
  78.       IF (Regs.AX AND $0030) = $30 THEN
  79.         BEGIN
  80.           ScreenBase := $b000;
  81.           Monochrome := TRUE
  82.         END
  83.       ELSE
  84.         BEGIN
  85.           ScreenBase := $b800;
  86.           Monochrome := FALSE
  87.         END
  88.     END; {of AdaptorType procedure}
  89.  
  90.   PROCEDURE CursorOff;
  91.     BEGIN
  92.       Regs.AX := $0100;
  93.       Regs.CX := $2000;
  94.       INTR (16,Regs);
  95.     END; {of CursorOff procedure}
  96.  
  97.   PROCEDURE NormCursorOn;
  98.     BEGIN
  99.       Regs.AX := $0100;   {AH = 1, set cursor size}
  100.       IF Monochrome THEN
  101.         Regs.CX := $0A0B
  102.       ELSE
  103.         Regs.CX := $0607;
  104.       INTR (16,Regs)
  105.     END; {of NormCursorOn procedure}
  106.  
  107.   PROCEDURE BlockCursorOn;
  108.     BEGIN
  109.       Regs.AX := $0100;   {AH = 1, set cursor size}
  110.       IF Monochrome THEN
  111.         Regs.CX := $020B
  112.       ELSE
  113.         Regs.CX := $0207;
  114.       INTR (16,Regs)
  115.     END; {of BlockCursorOn procedure}
  116.  
  117.   PROCEDURE ReverseVideo;
  118.     BEGIN
  119.       TextColor (0);
  120.       TextBackground (7);
  121.     END; {of ReverseVideo procedure}
  122.  
  123.   PROCEDURE BlinkOn;
  124.     BEGIN
  125.       TextAttr := TextAttr + Blink;
  126.     END;
  127.  
  128.   PROCEDURE Pad;
  129.     BEGIN
  130.       WHILE Length (LineToPad) < PadLength DO
  131.         LineToPad := LineToPad + ' ';
  132.     END; {of Pad procedure}
  133.  
  134.   PROCEDURE Strip;
  135.     VAR index : byte;
  136.     BEGIN
  137.       index := Length (LineToStrip);
  138.       WHILE LineToStrip[index] = ' ' DO
  139.         BEGIN
  140.           Delete (LineToStrip,index,1);
  141.           Dec (index)
  142.         END
  143.     END; {of Strip procedure}
  144.  
  145. {***************************************************************}
  146. PROCEDURE EditLine;
  147.   VAR
  148.     ExitFlag : boolean;
  149.     key : str2;
  150.  
  151.   PROCEDURE CursorRight;        {nested in Editline procedure}
  152.     BEGIN
  153.       Inc (cursor)
  154.     END; {of CursorRight procedure}
  155.  
  156.   PROCEDURE CursorLeft;         {nested in EditLine procedure}
  157.     BEGIN
  158.       Dec (cursor)
  159.     END; {of CursorLeft procedure}
  160.  
  161.   PROCEDURE CursorFront;        {nested in EditLine procedure}
  162.     BEGIN
  163.       cursor := col;
  164.     END; {of CursorFront procedure}
  165.  
  166.   PROCEDURE CursorEnd;          {nested in EditLine procedure}
  167.     VAR
  168.       position : byte;
  169.     BEGIN
  170.       position := Length (line);
  171.       WHILE line[position] = ' ' DO
  172.         Dec (position);
  173.       cursor := col + position
  174.     END; {of CursorEnd procedure}
  175.  
  176.   PROCEDURE WordRight;          {nested in EditLine procedure}
  177.     VAR position : byte;
  178.     BEGIN
  179.       position := cursor - col + 1;
  180.       WHILE line[position] <> ' ' DO
  181.         BEGIN
  182.           Inc (position);
  183.           IF position = fieldlength THEN Exit;
  184.         END;
  185.       Inc (position);
  186.       cursor := col + position - 1
  187.     END; {of WordRight procedure}
  188.  
  189.   PROCEDURE WordLeft;           {nested in Editline procedure}
  190.     VAR position : byte;
  191.     BEGIN
  192.       position := cursor - col + 1;
  193.       WHILE (line[position] <> ' ') AND (position >= 1) DO
  194.         Dec (position);
  195.       WHILE (line[position] = ' ') AND (position >= 1) DO
  196.         Dec (position);
  197.       WHILE (line[position] <> ' ') AND (position >= 1) DO
  198.           Dec (position);
  199.       cursor := col + position - 1;
  200.       IF cursor > col THEN Inc (cursor)
  201.     END; {of WordLeft procedure}
  202.  
  203.   PROCEDURE BackSpace;          {nested in EditLine procedure}
  204.     VAR
  205.       position : byte;
  206.     BEGIN
  207.       position := cursor - col + 1;
  208.       Delete (line, position - 1, 1);
  209.       CursorLeft;
  210.       line := line + ' '
  211.     END; {of BackSpace procedure}
  212.  
  213.   PROCEDURE DeleteChar;         {nested in EditLine procedure}
  214.     VAR
  215.       position : byte;
  216.     BEGIN
  217.       position := cursor - col + 1;
  218.       Delete (line, position, 1);
  219.       line := line + ' '
  220.     END; {of DeleteChar procedure}
  221.  
  222.   PROCEDURE DeleteWord;         {nested in EditLine procedure}
  223.     VAR
  224.       position : byte;
  225.     BEGIN
  226.       position := cursor - col + 1;
  227.       REPEAT
  228.         DeleteChar
  229.       UNTIL (COPY(line, position, 1) = ' ');
  230.       DeleteChar
  231.     END; {of DeleteWord procedure}
  232.  
  233.   PROCEDURE DeleteEOL;          {nested in EditLine procedure}
  234.     VAR
  235.       count, position : byte;
  236.     BEGIN
  237.       position := cursor - col + 1;
  238.       count := FieldLength - position + 1;
  239.       Delete (line, position, count);
  240.       Pad (line, FieldLength)
  241.     END; {of DeleteEOL procedure}
  242.  
  243.   PROCEDURE ToggleInsert;       {nested in EditLine procedure}
  244.     BEGIN
  245.       IF InsertFlag = TRUE THEN InsertFlag := FALSE
  246.         ELSE IF InsertFlag = FALSE THEN InsertFlag := TRUE
  247.     END; {of ToggleInsert procedure}
  248.  
  249.   PROCEDURE InsertChar;         {nested in EditLine procedure}
  250.     VAR
  251.       character : str1;
  252.       position : byte;
  253.     BEGIN
  254.       position := cursor - col + 1;
  255.       Delete (line, fieldlength,1);
  256.       character := key[1];
  257.       Insert (character, line, position);
  258.       CursorRight
  259.     END; {of InsertChar procedure}
  260.  
  261.   PROCEDURE ReplaceChar;        {nested in EditLine procedure}
  262.     VAR
  263.       position : byte;
  264.     BEGIN
  265.       position := cursor - col + 1;
  266.       line[position] := key[1];
  267.       CursorRight;
  268.     END; {of ReplaceChar procedure}
  269.  
  270.   PROCEDURE PositionCursor;     {nested in Editline procedure}
  271.     BEGIN
  272.       IF cursor < col THEN cursor := col;
  273.       IF cursor > col + fieldlength - 1 THEN cursor:=col;
  274.       Gotoxy (cursor, row);
  275.       IF InsertFlag = TRUE THEN
  276.         BlockCursorOn
  277.       ELSE
  278.         NormCursorOn;
  279.     END; {of PositionCursor procedure}
  280.  
  281.   PROCEDURE ExtendedCodes;      {nested in EditLine procedure}
  282.     BEGIN
  283.       CASE key[2] OF
  284.         #75:  CursorLeft; {left arrow}
  285.         #77:  CursorRight; {right arrow}
  286.         #71:  CursorFront; {Home}
  287.         #83:  DeleteChar; {Del}
  288.         #79:  CursorEnd; {End}
  289.         #82:  ToggleInsert; {Ins}
  290.         #115: WordLeft; {Ctrl-left arrow}
  291.         #116: WordRight; {Ctrl-right arrow}
  292.       ELSE
  293.         ExitFlag := TRUE
  294.       END; {of CASE statement}
  295.     END; {of ExtendedCodes procedure}
  296.  
  297.   PROCEDURE ControlCodes;       {nested in EditLine procedure}
  298.     BEGIN
  299.       CASE key[1] OF
  300.         #8:   BackSpace; {Backspace}
  301.         #5:   DeleteEOL;  {Ctrl-E}
  302.         #23:  DeleteWord; {Ctrl-W}
  303.       ELSE
  304.         ExitFlag := TRUE
  305.       END; {of CASE statement}
  306.     END; {of ControlCodes procedure}
  307.  
  308.   PROCEDURE ActOnKeypress;            {nested in EditLine procedure}
  309.     BEGIN
  310.       IF Length (key) = 2 THEN Extendedcodes
  311.         ELSE
  312.           BEGIN
  313.             IF key[1] IN [#0..#31] THEN ControlCodes;
  314.             IF key[1] IN [#32..#126] THEN
  315.               BEGIN
  316.                 IF InsertFlag = TRUE THEN InsertChar
  317.                   ELSE ReplaceChar
  318.               END
  319.           END;
  320.     END; {of ActOnKeypress procedure}
  321.  
  322.   PROCEDURE GetKeypress;        {nested in EditLine procedure}
  323.     BEGIN
  324.       key := GetKey
  325.     END; {of GetKeypress procedure}
  326.  
  327.   PROCEDURE DisplayLine;        {nested in EditLine procedure}
  328.     BEGIN
  329.       CursorOff;
  330.       if col>48 then col:=48;
  331.       GotoXY (col, row);
  332.       Write (line)
  333.     END; {of DisplayLine procedure}
  334.  
  335.   BEGIN {MAIN of EditLine procedure}
  336.     ExitFlag := FALSE;
  337.     Pad (line, FieldLength);
  338.     WHILE ExitFlag = FALSE DO
  339.       BEGIN
  340.         DisplayLine;
  341.         PositionCursor;
  342.         GetKeypress;
  343.         ActOnKeypress;
  344.       END;
  345.     Strip (line);
  346.     exit_key := key
  347.   END; {of EditLine procedure}
  348.  
  349. {Unit initialization - set ScreenBase, Monochrome variables}
  350. BEGIN
  351.   AdaptorType;
  352. END.
  353.